package com.buding.fx.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.buding.fx.common.enums.CodeButtonType;
import com.buding.fx.entity.CodeFormatConstant;
import com.buding.fx.entity.CodeFormatEntity;
import com.buding.fx.entity.JSONDemoEntity;
import com.buding.fx.validators.ExcelImportValidator;
import com.buding.fx.validators.JavaFieldValidator;
import com.buding.fx.validators.RequireAndLengthValidator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.jfoenix.controls.*;
import com.jfoenix.svg.SVGGlyph;
import com.jfoenix.svg.SVGGlyphLoader;
import com.jfoenix.validation.RequiredFieldValidator;
import com.jfoenix.validation.StringLengthValidator;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.input.Clipboard;
import javafx.scene.input.ClipboardContent;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.FileChooser;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.util.Callback;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Author: mingdongwei
 * @Date: 2024-05-03
 * @Description:
 * @Version: 1.0.0
 */
public class CodeFormatCreateThread extends Thread{
    private BorderPane borderPane;
    private Label lable;
    private Map<String, SVGGlyph> svgMap;
    private Stage primaryStage;

    private final String fileName = "icomoon.svg";

    private String labalChangeStyle = "-fx-background-color: #ffffff; -fx-font-size: 13px;-fx-text-fill: #e70909;-fx-font-weight: normal;-fx-border-width: 0 0 0 0";
    private String labelDefaultStyle = "-fx-background-color: #ECEAEA; -fx-font-size: 12px;-fx-text-fill: #2a2828;-fx-font-weight: normal;-fx-border-width: 0 0 0 0";

    private int svg_size = 10;

    private int button_font_size = 10;


    public CodeFormatCreateThread(BorderPane borderPane, Label lable, Map<String, SVGGlyph> svgMap,Stage primaryStage) {
        this.borderPane = borderPane;
        this.lable = lable;
        this.svgMap  = svgMap;
        this.primaryStage = primaryStage;
    }


    private String currentEditId = "";

    @SneakyThrows
    @Override
    public void run() {
        if (borderPane !=null && lable != null){
            FlowPane flowPane  = (FlowPane) borderPane.getTop();
            flowPane.getChildren().forEach(node -> {
                if (node instanceof JFXButton){
                    JFXButton curLabel = (JFXButton) node;
                    String userData = curLabel.getText();
                    if (!userData.equals(lable.getText())){
                       curLabel.setStyle(labelDefaultStyle);
                    }else{
                        curLabel.setStyle(labalChangeStyle);
                    }
                }
            });
            if (lable.getText().equals("JAVA")){
                FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/code/CodeFormatJava.fxml"));
                ScrollPane javaFxml = loader.load();
                FlowPane top = (FlowPane) borderPane.getTop();
                javaFxml.setPrefWidth(borderPane.getPrefWidth());
                javaFxml.setPrefHeight(borderPane.getPrefHeight()-top.getPrefHeight());
                if (javaFxml!=null){
                   javaFxml.setContent(createJaveNode());
                    borderPane.setBottom(javaFxml);
                }
            }else if (lable.getText().equals("MYSQL")){
                FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/code/CodeFormatMySql.fxml"));
                ScrollPane mysql = loader.load();
                FlowPane top = (FlowPane) borderPane.getTop();
                mysql.setPrefWidth(borderPane.getPrefWidth());
                mysql.setPrefHeight(borderPane.getPrefHeight()-top.getPrefHeight());
                if (mysql != null){
                    mysql.setContent(createMySqlNode());
                    borderPane.setBottom(mysql);
                }
            }
        }
    }

    private Node createJaveNode(){
        GridPane gridPane = new GridPane();

        HBox hBox = new HBox();
        hBox.setPrefWidth(borderPane.getPrefWidth()*0.15);
        hBox.setPrefHeight(borderPane.getPrefHeight()*0.3);
        hBox.setAlignment(Pos.TOP_CENTER);
        hBox.setPadding(new Insets(5,10,0,0));
        Label leftLabel = new Label("字段设置");
        leftLabel.getStyleClass().setAll("lbl","lbl-success");
        leftLabel.setStyle("-fx-pref-width: "+hBox.getPrefWidth() * 0.8+"; -fx-font-size: 12");
        hBox.getChildren().add(leftLabel);
        gridPane.add(hBox,0,0);

        Pane pane  = new Pane();
        /*BorderStroke borderStroke = new BorderStroke(null,null, Color.BLACK,null, null,null,BorderStrokeStyle.SOLID,null,null, BorderWidths.DEFAULT,new Insets(5,0,0,0));
        pane.setBorder(new Border(borderStroke));*/
        VBox h= new VBox();
        hBox.setSpacing(20);
        pane.setPrefWidth(borderPane.getPrefWidth()-hBox.getPrefWidth());
        pane.setPrefHeight(hBox.getPrefHeight());

        TableView<CodeFormatEntity> tableView = new TableView();
        tableView.setPrefHeight(pane.getPrefHeight()-35);
        tableView.setPrefWidth((pane.getPrefWidth()-hBox.getPrefWidth())*0.8);
        FlowPane buttonPanes = new FlowPane();
        buttonPanes.setHgap(10);
        buttonPanes.setStyle("-fx-background-color: #ffffff;");
        buttonPanes.setMaxWidth(pane.getPrefWidth());
        buttonPanes.setPrefHeight(35);
        buttonPanes.setAlignment(Pos.CENTER_LEFT);

        CheckBox checkBox = new JFXCheckBox("全选");
        checkBox.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                boolean isSelectAll = true;
                if (checkBox.isSelected()){
                    ObservableList<CodeFormatEntity> items = tableView.getItems();
                    for (CodeFormatEntity item : items) {
                        if (!item.getIsSelect().getValue()){
                            item.setIsSelect(new SimpleBooleanProperty(true));
                        }
                    }

                }else{

                    ObservableList<CodeFormatEntity> items = tableView.getItems();
                    for (CodeFormatEntity item : items) {
                        if (item.getIsSelect().getValue()){
                            item.setIsSelect(new SimpleBooleanProperty(false));
                        }
                    }
                }
                tableView.refresh();
            }
        });



        JFXButton addButton = createSvgButton(CodeButtonType.ADD);
        alertAddAndEdit(1,tableView,addButton,null);


        JFXButton deleteButton = createSvgButton(CodeButtonType.BATCH_DELETE);
        alertDelete(2,tableView,deleteButton,new ArrayList<>());


        JFXButton fileImportButton = createSvgButton(CodeButtonType.FILE_IMPORT);
        alertFileImport(tableView,fileImportButton);

        JFXButton jsonButton =  createSvgButton(CodeButtonType.JSON_IMPORT);
        alertJSON(tableView,jsonButton);

        buttonPanes.getChildren().addAll(checkBox,addButton,deleteButton,fileImportButton,jsonButton);


        double oneFiledWidth = tableView.getPrefWidth()/7;
        double noColmWidth = oneFiledWidth * 0.5;

        TableColumn<CodeFormatEntity, Boolean> is_selectCol = new TableColumn<CodeFormatEntity, Boolean>("选择");
        is_selectCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<CodeFormatEntity, Boolean>, ObservableValue<Boolean>>() {
            @Override
            public ObservableValue<Boolean> call(TableColumn.CellDataFeatures<CodeFormatEntity, Boolean> param) {
                SimpleBooleanProperty isSelect = param.getValue().getIsSelect();
                return isSelect;
            }
        });
        is_selectCol.setCellFactory(new Callback<TableColumn<CodeFormatEntity, Boolean>, TableCell<CodeFormatEntity, Boolean>>() {
            @Override
            public TableCell<CodeFormatEntity, Boolean> call(TableColumn<CodeFormatEntity, Boolean> param) {
                return new CodeFormatCreateThread.CheckBoxTableCell();
            }
        });
        is_selectCol.setVisible(true);
        is_selectCol.setPrefWidth(noColmWidth);



        TableColumn<CodeFormatEntity, String> noColm = new TableColumn("序号");
        noColm.setPrefWidth(noColmWidth);
        noColm.setResizable(false);
        noColm.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<CodeFormatEntity, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<CodeFormatEntity, String> param) {
                return param.getValue().getId();
            }
        });
        noColm.setCellFactory(new Callback<TableColumn<CodeFormatEntity, String>, TableCell<CodeFormatEntity, String>>() {
            @Override
            public TableCell<CodeFormatEntity, String> call(TableColumn<CodeFormatEntity, String> param) {
                return new TableCell<CodeFormatEntity,String>(){
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item != null && !empty) {
                            setText(item);
                            setAlignment(Pos.CENTER); // 设置内容居中
                        } else {
                            setText(null);
                        }
                    }
                };
            }
        });

        TableColumn<CodeFormatEntity, String> nameColm = new TableColumn("名称");
        nameColm.setPrefWidth(oneFiledWidth);
        nameColm.setResizable(false);
        nameColm.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<CodeFormatEntity, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<CodeFormatEntity, String> param) {
                return param.getValue().getName();
            }
        });
        nameColm.setCellFactory(new Callback<TableColumn<CodeFormatEntity, String>, TableCell<CodeFormatEntity, String>>() {
            @Override
            public TableCell<CodeFormatEntity, String> call(TableColumn<CodeFormatEntity, String> param) {
                return new TableCell<CodeFormatEntity,String>(){
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item != null && !empty) {
                            setText(item);
                            setAlignment(Pos.CENTER); // 设置内容居中
                        } else {
                            setText(null);
                        }
                    }
                };
            }
        });

        TableColumn<CodeFormatEntity, String> engColm = new TableColumn("英文标识");
        engColm.setResizable(false);
        engColm.setPrefWidth(oneFiledWidth);
        engColm.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<CodeFormatEntity, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<CodeFormatEntity, String> param) {
                return param.getValue().getEng();
            }
        });
        engColm.setCellFactory(new Callback<TableColumn<CodeFormatEntity, String>, TableCell<CodeFormatEntity, String>>() {
            @Override
            public TableCell<CodeFormatEntity, String> call(TableColumn<CodeFormatEntity, String> param) {
                return new TableCell<CodeFormatEntity,String>(){
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item != null && !empty) {
                            setText(item);
                            setAlignment(Pos.CENTER); // 设置内容居中
                        } else {
                            setText(null);
                        }
                    }
                };
            }
        });


        TableColumn<CodeFormatEntity, String> datatypeColm = new TableColumn("数据类型");
        datatypeColm.setPrefWidth(oneFiledWidth);
        datatypeColm.setResizable(false);
        datatypeColm.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<CodeFormatEntity, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<CodeFormatEntity, String> param) {
                return param.getValue().getDateType();
            }
        });
        datatypeColm.setCellFactory(new Callback<TableColumn<CodeFormatEntity, String>, TableCell<CodeFormatEntity, String>>() {
            @Override
            public TableCell<CodeFormatEntity, String> call(TableColumn<CodeFormatEntity, String> param) {
                return new TableCell<CodeFormatEntity,String>(){
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item != null && !empty) {
                            setAlignment(Pos.CENTER); // 设置内容居中
                            JFXComboBox jfxComboBox = new JFXComboBox();
                            List<String> items = Arrays.asList("字符","数字","日期","布尔");
                            jfxComboBox.setItems(FXCollections.observableArrayList(items));
                            jfxComboBox.setDisable(true);
                            int index = 0;
                            for (int i = 0; i < items.size(); i++) {
                                if (items.get(i).equals(item)){
                                    index = i;
                                }
                            }
                            jfxComboBox.getSelectionModel().select(index);
                            setGraphic(jfxComboBox);
                        } else {
                            setGraphic(null);
                        }
                    }
                };
            }
        });

        TableColumn<CodeFormatEntity, String> remarkColm = new TableColumn("备注");
        remarkColm.setPrefWidth(oneFiledWidth);
        remarkColm.setResizable(false);
        remarkColm.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<CodeFormatEntity, String>, ObservableValue<String>>() {
            @Override
            public ObservableValue<String> call(TableColumn.CellDataFeatures<CodeFormatEntity, String> param) {
                return  param.getValue().getRemark();
            }
        });
        remarkColm.setCellFactory(new Callback<TableColumn<CodeFormatEntity, String>, TableCell<CodeFormatEntity, String>>() {
            @Override
            public TableCell<CodeFormatEntity, String> call(TableColumn<CodeFormatEntity, String> param) {
                return new TableCell<CodeFormatEntity,String>(){
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item != null && !empty) {
                            Tooltip tooltip = new Tooltip(item);
                            Tooltip.install(this,tooltip);
                            setText(item);
                            setTooltip(tooltip);
                            setAlignment(Pos.CENTER); // 设置内容居中
                        } else {
                            setText(null);
                        }
                    }
                };
            }
        });

        TableColumn<CodeFormatEntity,List<String>> editsColm = new TableColumn("操作");
        editsColm.setResizable(false);
        double ediweidth = tableView.getPrefWidth()-is_selectCol.getPrefWidth()-noColm.getPrefWidth()-nameColm.getPrefWidth()-
                engColm.getPrefWidth()-datatypeColm.getPrefWidth()-remarkColm.getPrefWidth()- 30;
        editsColm.setPrefWidth(ediweidth);
        editsColm.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<CodeFormatEntity, List<String>>, ObservableValue<List<String>>>() {
            @Override
            public ObservableValue<List<String>> call(TableColumn.CellDataFeatures<CodeFormatEntity, List<String>> param) {
                List<String> buttons = param.getValue().getButtons();
                ObjectProperty<List<String>> r = new SimpleObjectProperty<>(buttons);
                return r;
            }
        });


        editsColm.setCellFactory(new Callback<TableColumn<CodeFormatEntity, List<String>>, TableCell<CodeFormatEntity, List<String>>>() {

            @Override
            public TableCell<CodeFormatEntity, List<String>> call(TableColumn<CodeFormatEntity, List<String>> param) {
                return  new TableCell<CodeFormatEntity,List<String>>(){

                    @SneakyThrows
                    @Override
                    protected void updateItem(List<String> buttons, boolean empty) {
                        super.updateItem(buttons, empty);
                        if (!empty && buttons.size()>0) {
                            HBox hbox = new HBox();
                            setAlignment(Pos.CENTER); // 设置内容居中
                            hbox.setAlignment(Pos.CENTER);
                            for (String s : buttons) {
                                if ("编辑".equals(s)){
                                    JFXButton editBt = createSvgButton(CodeButtonType.EDIT);
                                    alertAddAndEdit(2,tableView,editBt,getTableView().getItems().get(getIndex()));
                                    hbox.getChildren().add(editBt);
                                }else if("删除".equals(s)){
                                    JFXButton deleteBt = createSvgButton(CodeButtonType.DELLTE);
                                    CodeFormatEntity code = getTableView().getItems().get(getIndex());
                                    alertDelete(1, tableView, deleteBt, Arrays.asList(code));
                                    hbox.getChildren().add(deleteBt);
                                }
                            }
                            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
                            setGraphic(hbox);
                        } else {
                            setGraphic(null);
                        }
                    }
                };
            }
        });

        tableView.getColumns().addAll(is_selectCol,noColm,nameColm,engColm,datatypeColm,remarkColm,editsColm);
        tableView.getItems().addAll(CodeFormatEntity.getDemoList());

        h.getChildren().addAll(buttonPanes,tableView);
        pane.getChildren().add(h);
        gridPane.add(pane,1,0);


        //其他元素设置
        HBox otherBox = new HBox();
        otherBox.setPrefWidth(borderPane.getPrefWidth()*0.15);
        otherBox.setPrefHeight(borderPane.getPrefHeight()*0.2);
        otherBox.setAlignment(Pos.TOP_CENTER);
        otherBox.setPadding(new Insets(5,10,0,0));
        Label otherLabel = new Label("其它设置");
        otherLabel.getStyleClass().setAll("lbl","lbl-success");
        otherLabel.setStyle("-fx-pref-width: "+otherBox.getPrefWidth() * 0.8+"; -fx-font-size: 12");
        otherBox.getChildren().add(otherLabel);

        FlowPane otherRight = new FlowPane();
        otherRight.setMaxWidth((borderPane.getPrefWidth()-otherBox.getPrefWidth())*0.7);
        otherRight.setMaxHeight(hBox.getPrefHeight());


        otherRight.getChildren().addAll(createOherNode("Author"),createOherNode("PackageName"),createOherNode("DateTimeType")

        );


        gridPane.add(otherBox,0,1);
        gridPane.add(otherRight,1,1);
        return  gridPane;
    }

    private Node createMySqlNode(){
        GridPane gridPane = new GridPane();
        JFXButton button = new JFXButton("元素生成");
        button.setButtonType(JFXButton.ButtonType.RAISED);
        button.getStyleClass().add("custom-jfx-button-raised");
        HBox hBox = new HBox();
        hBox.getChildren().add(button);
        gridPane.add(hBox,0,0);
        return  gridPane;
    }

    private void setTableViewAllSelection(TableView<CodeFormatEntity> tableView) {
        // 全选实现
        tableView.setOnContextMenuRequested(event -> {
            SelectionModel<CodeFormatEntity> selectionModel = tableView.getSelectionModel();
            CodeFormatEntity selectedItem = selectionModel.getSelectedItem();
            boolean newSelect = !selectedItem.getIsSelect().get();
            selectedItem.setIsSelect(new SimpleBooleanProperty(newSelect));
        });
    }

    private class CheckBoxTableCell extends TableCell<CodeFormatEntity, Boolean> {
        private final CheckBox checkBox = new CheckBox();

        CheckBoxTableCell() {
            checkBox.setOnAction(event -> {
                CodeFormatEntity item = getTableView().getItems().get(getIndex());
                item.setIsSelect(new SimpleBooleanProperty(checkBox.isSelected()));
            });
            setAlignment(Pos.CENTER);
        }

        @Override
        protected void updateItem(Boolean selected, boolean empty) {
            super.updateItem(selected, empty);
            if (empty) {
                setGraphic(null);
            } else {
                checkBox.setSelected(selected);
                setGraphic(checkBox);
                setAlignment(Pos.CENTER);
            }
        }
    }


    private void alertDelete(int alertType,TableView<CodeFormatEntity> tableView ,Button node,List<CodeFormatEntity> codes){
        node.setOnAction(action -> {
            if (alertType==2){
                ObservableList<CodeFormatEntity> items = tableView.getItems();
                for (CodeFormatEntity item : items) {
                    if (item.getIsSelect().getValue()){
                        codes.add(item);
                    }
                }
            }
            JFXAlert alert = new JFXAlert((Stage) node.getScene().getWindow());
            alert.initModality(Modality.APPLICATION_MODAL);
            alert.setOverlayClose(false);
            JFXDialogLayout layout = new JFXDialogLayout();
            Label heading = new Label("删除提示");
            heading.setStyle("-fx-font-size: 14");
            layout.setHeading(heading);

            Label content = new Label("您确认删除这些数据数据吗？");
            SVGGlyph editNewSvg = null;
            try {
                editNewSvg = SVGGlyphLoader.getIcoMoonGlyph(fileName + "." + "info");
            } catch (Exception e) {
                e.printStackTrace();
            }
            editNewSvg.setSize(svg_size);
            editNewSvg.setFill(Color.web("#1572DD"));
            content.setStyle("-fx-font-size: 12");
            content.setGraphic(editNewSvg);
            layout.setBody(content);
            JFXButton closeButton = createSvgButton(CodeButtonType.CONFIRM);
            closeButton.getStyleClass().add("dialog-accept");
            closeButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    ObservableList<CodeFormatEntity> items = tableView.getItems();
                    for (CodeFormatEntity code : codes) {
                        items.remove(code);
                    }
                    for (int i = 0; i < items.size(); i++) {
                        items.get(i).setId(new SimpleStringProperty(i+1+""));
                    }
                    tableView.refresh();
                    alert.close();
                }
            });
            JFXButton cancleButton = createSvgButton(CodeButtonType.CANCLE);
            cancleButton.getStyleClass().add("dialog-cancle");
            cancleButton.setOnAction(event -> alert.close());
            layout.setActions(cancleButton,closeButton);
            alert.setContent(layout);
            alert.show();
        });
    }


    private void alertFileImport(TableView<CodeFormatEntity> tableView ,Button node){
        node.setOnAction(action -> {
            AtomicReference<List<Object>> excelRows = new AtomicReference<>();
            AtomicBoolean defaultValidateResult = new AtomicBoolean(true);
            JFXAlert alert = new JFXAlert((Stage) node.getScene().getWindow());
            alert.initModality(Modality.APPLICATION_MODAL);
            alert.setOverlayClose(false);
            JFXDialogLayout layout = new JFXDialogLayout();
            Label heading = new Label("文件导入");
            heading.setStyle("-fx-font-size: 14");
            layout.setHeading(heading);
            HBox hbox = new HBox();
            Label label = new Label("请导入文件：");
            label.setStyle("-fx-font-size: 12");
            JFXTextField jfxTextField = new JFXTextField();
            jfxTextField.setEditable(false);
            jfxTextField.setPromptText("请导入以.xls、xlsx为后缀的文件");
            jfxTextField.setTooltip(new Tooltip("导入的excel文件只需要导入第一行，且每列只能以字母开头长度不能超过10的字符"));
            SVGGlyph errorSvg = svgMap.get("268");
            errorSvg.setSize(10);
            errorSvg.setFill(Color.web("#990000"));
            SVGGlyph svg = svgMap.get("542");
            svg.setSize(12);
            JFXButton filemportButton = new JFXButton("",svg);
            filemportButton.setOnAction(event -> {
                FileChooser fileChooser = new FileChooser();
                fileChooser.setTitle("选择文件");
                fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("Text Files", "*.xls","*.xlsx"));
                File file = fileChooser.showOpenDialog(primaryStage);
                if (file != null) {
                    jfxTextField.setText( file.getAbsolutePath());
                    ExcelReader reader = ExcelUtil.getReader(file);
                    List<List<Object>> allRows = reader.read();
                    System.out.println("CodeFormatCreateThread.alertFileImport："+allRows);
                    List<Object> firstRows = allRows.get(0);
                    System.out.println("导入文件列： "+firstRows);
                    ExcelImportValidator excelImportValidator = new ExcelImportValidator(10,firstRows);
                    excelImportValidator.setIcon(errorSvg);
                    jfxTextField.getValidators().addAll(excelImportValidator);
                    boolean vresult = jfxTextField.validate();
                    defaultValidateResult.set(vresult);
                    if (vresult){
                        excelRows.set(firstRows);
                    }
                    reader.close();
                }
            });

            hbox.getChildren().addAll(label,jfxTextField,filemportButton);
            layout.setBody(hbox);
            JFXButton closeButton = createSvgButton(CodeButtonType.CONFIRM);
            closeButton.getStyleClass().add("dialog-accept");
            closeButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    RequiredFieldValidator requiredFieldValidator = new RequiredFieldValidator();
                    requiredFieldValidator.setIcon(errorSvg);
                    requiredFieldValidator.setMessage("导入文件不能为空");
                    jfxTextField.getValidators().addAll(requiredFieldValidator);
                    defaultValidateResult.set(jfxTextField.validate());
                    if (defaultValidateResult.get()){
                        //全部校验通过更新tableview
                        List<Object> objects = excelRows.get();
                        List<CodeFormatEntity> codeFormatEntities = formatRows(objects);
                        tableView.getItems().addAll(codeFormatEntities);

                        for (int i = 0; i < tableView.getItems().size(); i++) {
                            tableView.getItems().get(i).setId(new SimpleStringProperty(i+""));
                        }
                        tableView.refresh();
                        alert.close();
                    }
                }
            });
            JFXButton cancleButton = createSvgButton(CodeButtonType.CANCLE);
            cancleButton.getStyleClass().add("dialog-cancle");
            cancleButton.setOnAction(event -> alert.close());
            layout.setActions(cancleButton,closeButton);
            alert.setContent(layout);
            alert.show();
        });
    }

    private void alertJSON(TableView<CodeFormatEntity> tableView,JFXButton button){
        button.setOnAction(action ->{
            boolean validateResult = false;
            JFXAlert alert = new JFXAlert((Stage) button.getScene().getWindow());
            alert.initModality(Modality.APPLICATION_MODAL);
            alert.setOverlayClose(false);
            JFXDialogLayout layout = new JFXDialogLayout();

            double totalWidth = borderPane.getPrefWidth() * 2/3;
            double totalHeight = borderPane.getPrefHeight() * 2 / 3;
            layout.setPrefWidth(totalWidth);
            layout.setPrefHeight(totalHeight);
            layout.setAlignment(Pos.CENTER);

            HBox heading = new HBox();
            Label titleLabel = new Label("JSON格式化");
            titleLabel.setStyle("-fx-font-size: 12");
            Border border = new Border(new BorderStroke(Color.web("#c2bfbf"), BorderStrokeStyle.SOLID, new CornerRadii(0), new BorderWidths(0,0,1,0)));
            //heading.setBorder(border);
            heading.setAlignment(Pos.CENTER_LEFT);
            heading.setSpacing(20);

            layout.setHeading(heading);
            VBox bodyBox = new VBox();
            TextArea textArea = new TextArea();
            textArea.setPrefWidth(layout.getPrefWidth());
            textArea.setPrefHeight(layout.getPrefWidth());
            textArea.setWrapText(true);
            textArea.setId("j-trea");

            Label label = new Label("");
            textArea.textProperty().addListener(new ChangeListener<String>() {
                @Override
                public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
                    try {
                        if (StringUtils.isNoneEmpty(newValue)){
                            JSON.parse(newValue);
                            createSvgLable(label,"老铁，json格式正确",10,"ok");
                        }
                    }catch (Exception e){
                        createSvgLable(label,"老铁，json格式有问题",10,"error");
                   }
                }
            });
            ObjectMapper mapper = new ObjectMapper();
            mapper.enable(SerializationFeature.INDENT_OUTPUT);
            //JSON样例
            JFXButton jsonDemoButton = createSvgButton(CodeButtonType.JSON_DEMO);
            jsonDemoButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    String s = null;
                    try {
                        s = mapper.writeValueAsString(JSONDemoEntity.getJSONDemoStr());
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                    }
                    JSONObject object = JSONObject.parseObject(JSONDemoEntity.getJSONDemoStr());
                    String pretty = JSON.toJSONString(object, SerializerFeature.PrettyFormat, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteDateUseDateFormat);

                    String jsonString = JSON.toJSONString(JSONDemoEntity.getJSONDemoStr(), true);
                    textArea.setText(pretty);
                }
            });


            //一键美化
            JFXButton beatyButton = createSvgButton(CodeButtonType.JSON_BEATY);
            beatyButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    try {
                        mapper.writeValueAsString(textArea.getText());
                    } catch (JsonProcessingException e) {

                    }
                }
            });


            //一键复制
            JFXButton copyButton = createSvgButton(CodeButtonType.JSON_COPY);
            copyButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    Clipboard clipboard = Clipboard.getSystemClipboard();
                    // 创建剪贴板内容
                    ClipboardContent content = new ClipboardContent();
                    // 将文本添加到剪贴板内容中
                    content.putString(textArea.getText());
                    // 将剪贴板内容复制到系统剪贴板
                    clipboard.setContent(content);
                    textArea.selectAll();
                }
            });

            heading.getChildren().addAll(titleLabel,jsonDemoButton,beatyButton,copyButton);


            bodyBox.setSpacing(10);
            bodyBox.getChildren().addAll(textArea,label);
            layout.setBody(bodyBox);

            //取消
            JFXButton cancleButton = createSvgButton(CodeButtonType.CANCLE);
            cancleButton.getStyleClass().add("dialog-cancle");
            cancleButton.setOnAction(event -> alert.close());


            //确认
            JFXButton confirmButton = createSvgButton(CodeButtonType.CONFIRM);
            confirmButton.getStyleClass().add("dialog-accept");
            confirmButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    try {
                        String text = textArea.getText();
                        if (StringUtils.isNoneEmpty(text)){
                            List<CodeFormatEntity> codeFormatEntities = formatJsonRows(text);
                            ObservableList<CodeFormatEntity> items = tableView.getItems();
                            items.addAll(codeFormatEntities);
                            for (int i = 0; i < items.size(); i++) {
                                items.get(i).setId(new SimpleStringProperty(i+""));
                            }
                            tableView.refresh();
                            alert.close();

                        }
                    }catch (Exception e){
                        createSvgLable(label,"老铁，json格式有问题，再仔细检查检查",10,"error");
                    }
                }
            });

            layout.setActions(cancleButton,confirmButton);
            alert.setContent(layout);
            alert.show();

        });
    }

    /**
     * 新增和编辑弹窗
     * @param alertType 1:新增 2：编辑
     * @param tableView
     * @param node
     * @param codeFormatEntity
     */
    private void alertAddAndEdit(int alertType,TableView<CodeFormatEntity> tableView ,Button node,CodeFormatEntity codeFormatEntity){
        node.setOnAction(action -> {
            String heading = "新增字段";
            if (alertType==2){
                heading = "编辑字段";
                currentEditId = codeFormatEntity.getId().getValue();
            }
            JFXAlert alert = new JFXAlert((Stage) node.getScene().getWindow());
            alert.initModality(Modality.APPLICATION_MODAL);
            alert.setOverlayClose(false);
            JFXDialogLayout layout = new JFXDialogLayout();
            layout.setHeading(createHeading(heading));
            Node body = createBody(tableView,codeFormatEntity);
            layout.setBody(body);
            JFXButton closeButton = createSvgButton(CodeButtonType.CONFIRM);
            closeButton.getStyleClass().add("dialog-accept");
            closeButton.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    GridPane gridPane = (GridPane)body;
                    doEditOrAdd(alertType,gridPane,tableView);
                    tableView.refresh();
                    alert.close();
                }
            });

            JFXButton cancleButton = createSvgButton(CodeButtonType.CANCLE);
            cancleButton.getStyleClass().add("dialog-cancle");
            cancleButton.setOnAction(event -> alert.close());
            layout.setActions(cancleButton,closeButton);
            alert.setContent(layout);
            alert.show();
        });
    }

    private Node createHeading(String title){
        Label label = new Label(title);
        label.setStyle("-fx-font-size: 14");
        return label;
    }


    private Node createBody(TableView<CodeFormatEntity> tableView,CodeFormatEntity codeFormatEntity){
        GridPane gridPane = new GridPane();
        gridPane.setStyle("-fx-font-size: 12");
        gridPane.setVgap(20);
        String labelStyle = "-fx-font-size: 12";

        SVGGlyph errorSvg = svgMap.get("268");
        errorSvg.setSize(12);
        errorSvg.setFill(Color.web("#990000"));
        errorSvg.setRotate(180);


        Label nameLabel = new Label("字段名称");
        nameLabel.setStyle(labelStyle);

        JFXTextField nameField = new JFXTextField();
        nameField.setPromptText("请输入字段名称");
        if (codeFormatEntity != null && codeFormatEntity.getName().getValue() !=null ){
            nameField.setText(codeFormatEntity.getName().getValue());
        }
        nameField.setId(CodeFormatConstant.CODE_FORMAT_ENTITY_NAME_ID);
        nameField.setTooltip(new Tooltip("请输入长度不超过20字符的中文"));
        RequireAndLengthValidator nameValidator = new RequireAndLengthValidator(20);
        nameValidator.setIcon(errorSvg);
        nameField.getValidators().addAll(nameValidator);
        nameField.focusedProperty().addListener((o, oldVal, newVal) -> {
            if (!newVal) {
                nameField.validate();
            }
        });


        Label engLabel = new Label("字段英文标识");
        engLabel.setStyle(labelStyle);
        JFXTextField engField = new JFXTextField();
        engField.setPromptText("请输入字段英文标识");
        engField.setId(CodeFormatConstant.CODE_FORMAT_ENTITY_ENG_ID);

        engField.setTooltip(new Tooltip("请输入以字母开头，并且只能包含字母、数字和下划线，长度不能超过50的字符"));
        if (codeFormatEntity != null && codeFormatEntity.getEng().getValue() !=null ){
            engField.setText(codeFormatEntity.getEng().getValue());
        }
        JavaFieldValidator javaFieldValidator = new JavaFieldValidator(50);
        javaFieldValidator.setIcon(errorSvg);
        engField.getValidators().addAll(javaFieldValidator);
        engField.focusedProperty().addListener((o, oldVal, newVal) -> {
            if (!newVal) {
                engField.validate();
            }
        });

        Label dateTypeLable = new Label("字段类型");
        dateTypeLable.setStyle(labelStyle);
        JFXComboBox comboBox = new JFXComboBox();
        comboBox.setId(CodeFormatConstant.CODE_FORMAT_ENTITY_DATETYPE_ID);
        List<String> items = Arrays.asList("字符","数字","布尔","日期");
        ObservableList<String> oItems = FXCollections.observableArrayList(items);
        comboBox.setItems(oItems);
        int index = 0;
        if (codeFormatEntity!=null && codeFormatEntity.getDateType().getValue()!=null){
            for (int i = 0; i < items.size(); i++) {
                if (items.get(i).equals(codeFormatEntity.getDateType().getValue())){
                    index = i;
                }
            }
        }
        comboBox.getSelectionModel().select(index);
        Label remarkLabel = new Label("字段备注");
        remarkLabel.setStyle(labelStyle);
        JFXTextField remarkField = new JFXTextField();
        remarkField.setPromptText("请输入字段备注");
        remarkField.setId(CodeFormatConstant.CODE_FORMAT_ENTITY_REMARK_ID);
        if (codeFormatEntity != null && codeFormatEntity.getRemark().getValue() !=null ){
            remarkField.setText(codeFormatEntity.getRemark().getValue());
        }
        remarkField.setTooltip(new Tooltip("长度不能超过50"));
        StringLengthValidator remarkValidator = new StringLengthValidator(50);
        remarkValidator.setMessage("备注长度不能超过50个字符");
        remarkValidator.setIcon(errorSvg);
        remarkField.getValidators().add(remarkValidator);
        remarkField.focusedProperty().addListener((o, oldVal, newVal) -> {
            if (!newVal) {
                remarkField.validate();
            }
        });

        gridPane.add(nameLabel,0,0);
        gridPane.add(nameField,1,0);
        gridPane.add(engLabel,0,1);
        gridPane.add(engField,1,1);
        gridPane.add(dateTypeLable,0,2);
        gridPane.add(comboBox,1,2);
        gridPane.add(remarkLabel,0,3);
        gridPane.add(remarkField,1,3);
        return gridPane;
    }

    private void doEditOrAdd(int alertType,Node alertBody,TableView<CodeFormatEntity> tableView){
        JFXTextField nameField = (JFXTextField) alertBody.lookup("#"+CodeFormatConstant.CODE_FORMAT_ENTITY_NAME_ID);
        JFXTextField engField = (JFXTextField) alertBody.lookup("#"+CodeFormatConstant.CODE_FORMAT_ENTITY_ENG_ID);
        JFXComboBox dateTypeField = (JFXComboBox) alertBody.lookup("#"+CodeFormatConstant.CODE_FORMAT_ENTITY_DATETYPE_ID);
        JFXTextField remarkField = (JFXTextField) alertBody.lookup("#"+CodeFormatConstant.CODE_FORMAT_ENTITY_REMARK_ID);
        if (alertType==1){//新增
            CodeFormatEntity codeFormatEntity = new CodeFormatEntity();
            codeFormatEntity.setId(new SimpleStringProperty("0"));
            codeFormatEntity.setButtons(Arrays.asList("编辑","删除"));
            if (nameField!=null){
                codeFormatEntity.setName(new SimpleStringProperty(nameField.getText()));
            }
            if (engField !=null){
                codeFormatEntity.setEng(new SimpleStringProperty(engField.getText()));
            }
            if (dateTypeField !=null){
                codeFormatEntity.setDateType(new SimpleStringProperty((String) dateTypeField.getSelectionModel().getSelectedItem()));
            }
            if (remarkField !=null){
                codeFormatEntity.setRemark(new SimpleStringProperty(remarkField.getText()));
            }
            tableView.getItems().add(0,codeFormatEntity);
        }else{
            for (CodeFormatEntity item : tableView.getItems()) {
                if (currentEditId != null && item.getId().getValue().equals(currentEditId)){
                    if (nameField!=null){
                        item.setName(new SimpleStringProperty(nameField.getText()));
                    }
                    if (engField !=null){
                        item.setEng(new SimpleStringProperty(engField.getText()));
                    }
                    if (dateTypeField !=null){
                        item.setDateType(new SimpleStringProperty((String) dateTypeField.getSelectionModel().getSelectedItem()));
                    }
                    if (remarkField !=null){
                        item.setRemark(new SimpleStringProperty(remarkField.getText()));
                    }
                }
            }

        }
    }

    /**
     * 创建成功或者失败的 Label
     * @param text
     * @param size
     * @param labelType
     * @return
     */
    private Label createSvgLable(Label label,String text,int size,String labelType){
        label.setFont(Font.font(size));
        label.setText(text);
        String color = "";
        String svgName = "";
        switch (labelType){
            case "ok":
                color = "#069a19";
                svgName = "check-circle";
                break;
            case "error":
                color = "#b31a1a";
                svgName = "warning";
                break;
        }

        label.setTextFill(Color.web(color));
        try {
            SVGGlyph svg = null;
            if (labelType.equals("error")){
                svg = svgMap.get("108");
                svg.setRotate(180);
            }else{
                svg = SVGGlyphLoader.getIcoMoonGlyph(fileName + "." + svgName);
            }
            svg.setFill(Color.web(color));
            svg.setSize(size+2);
            label.setGraphic(svg);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return label;
    }

    /**
     * 创建不同带svg矢量图标的按钮
     * @return
     */
    private JFXButton createSvgButton(CodeButtonType buttonType){
        int svgSize = 10;
        int fontSize = 10;
        SVGGlyph svg  = null;
        String svgName = null;
        String fill = null;
        switch (buttonType){
            case ADD:
                svgName = "plus";
                fill = "#268408";
                break;
            case CONFIRM:
                svgName = "check";
                fill = "#03A9F4";
                break;
            case EDIT:
                svgName = "pencil";
                fill = "#1572DD";
                break;
            case DELLTE:
                svgName = "minus";
                fill = "#D0021B";
                break;
            case BATCH_DELETE:
                svgName = "trash-0";
                fill = "#DF180E";
                break;
            case CANCLE:
                svgName = "close,remove,times";
                fill = "#9fa2a3";
                break;
            case FILE_IMPORT:
                svgName = "folder";
                fill = "#409EFF";
                break;
            case JSON_IMPORT:
                svgName = "file";
                fill = "#1a4d4d";
                break;
            case JSON_DEMO:
                svgName = "wordpress";
                fill = "#0ac3f2";
                break;
            case JSON_BEATY:
                svgName = "hand-o-up";
                fill = "#996600";
                break;
            case JSON_COPY:
                svgName = "files-empty";
                fill = "#047e0c";
        }
        try {
            if (buttonType==CodeButtonType.CANCLE){
                svg = svgMap.get("15");
            }else if (buttonType==CodeButtonType.BATCH_DELETE){
                svg = svgMap.get("461");
                svg.setRotate(180);
            }else{
                svg = SVGGlyphLoader.getIcoMoonGlyph(fileName + "." + svgName);
            }
            svg.setSize(svgSize);
            svg.setFill(Color.web(fill));
        } catch (Exception e) {
            e.printStackTrace();
        }
        JFXButton button = new JFXButton(buttonType.getDesc());
        button.setStyle("-fx-font-size: "+fontSize+"; -fx-text-fill: "+fill+";");
        button.setGraphic(svg);
        return button;
    }


    private List<CodeFormatEntity> formatRows(List<Object> rows){
        List<CodeFormatEntity> returnList = new ArrayList<>();
        for (Object row : rows) {
            CodeFormatEntity codeFormatEntity = new CodeFormatEntity();
            codeFormatEntity.setButtons(Arrays.asList("编辑","删除"));
            codeFormatEntity.setEng(new SimpleStringProperty(row.toString()));
            codeFormatEntity.setName(new SimpleStringProperty("默认备注"));
            codeFormatEntity.setDateType(new SimpleStringProperty("字符"));
            returnList.add(codeFormatEntity);
        }

        return returnList;
    }


    private List<CodeFormatEntity> formatJsonRows(String jsonStr){
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        List<CodeFormatEntity> returnList = new ArrayList<>();
        Set<String> keySet = jsonObject.keySet();
        for (String key : keySet) {
            String value = (String) jsonObject.get(key);
            CodeFormatEntity codeFormatEntity = new CodeFormatEntity();
            codeFormatEntity.setButtons(Arrays.asList("编辑","删除"));
            codeFormatEntity.setEng(new SimpleStringProperty(key));
            codeFormatEntity.setName(new SimpleStringProperty(value));
            codeFormatEntity.setDateType(new SimpleStringProperty("字符"));
            codeFormatEntity.setRemark(new SimpleStringProperty("默认备注"));
            returnList.add(codeFormatEntity);
        }
        return  returnList;
    }

    /**
     * 生成不同类型的Node
     * @param type
     * @return
     */
    private Node createOherNode(String type){
        HBox hBox = new HBox();
        Label label = new Label();
        Node subNode = null;
        switch (type){
            case "Author":
                label.setText("作者");
                subNode = new TextField();
                break;
            case "PackageName":
                label.setText("包名");
                subNode = new TextField();
                break;
            case "DateTimeType":
                label.setText("时间类型");
                subNode = new TextField();
        }
        hBox.getChildren().addAll(label,subNode);
        return hBox;
    }

}
